/*
 * jsQuick JavaScript Library v1.1
 * 
 * Copyright 2011, mr.P
 * 
 * Date: 01.09.2011 17:15:01
 */
(function (window, undefined) {
  var document = window.document;
  var location = window.location;
  // очередь анимаций
  var t_anims = [],
      nAnims  = 0;
  var jsQuick    = (function () {
    // локальная копия
    var jsQuick = function(search) {
      return new jsQuick.main.init(search);
    },
    
    // основные р. выражения
    rExpr = /^(#([\w\-]+)$)/,
    
    // правый/левый trim
    trimLeft  = /^\s+/, 
    trimRight = /\s+$/,
    
    toString = Object.prototype.toString;
    
    jsQuick.main = jsQuick.prototype = {
      constructor: jsQuick,
      init: function(search) {
        var elem, match;
        // $(пустой/не существующий)
        if (!search) {return this;}
        
        // $(DOM элемент)
        if (search.nodeType) {
          this.context = this[0] = search;
          this.length = 1;
          return this;
        }
        
        // $(body)
        if (search == "body") {
          this.context = document;
          this[0] = document.body;
          this.search = search;
          this.length = 1;
          return this;
        }
        
        // $("#id")  
        if (typeof search === "string") {
          match = rExpr.exec(search);
          if (match) {
            elem = document.getElementById(match[2]);
            if (elem) {
              this.length = 1;
              this[0] = elem;
            }
            this.context = document;
            this.search  = search;
            return this;
          }
        }
      },
      obj: function() {return this[0];},
      search: "",
      length: 0,
      // свойства
      html: function(value) {
        if (value === undefined) {return this[0].innerHTML;}
        else {this[0].innerHTML = value;}
      },
      className: function(value) {
        if (value === undefined) {return this[0].className;}
        else {this[0].className = value;}
      },
      value: function(value) {
        if (value === undefined) {return this[0].value;}
        else {this[0].value = value;}
      },
      src: function(value) {
        if (value === undefined) {return this[0].src;}
        else {this[0].src = value;}
      },
      // css
      css: function(name, value) {
        style = cssNameValid(name);
        this[0].style[style] = value; 
      },
      height: function (value) {this[0].style.height = value;},
      width: function (value) {this[0].style.width = value;},
      display: function(value) {this[0].style.display = value;},
      show: function () {this.display("block");},
      hide: function () {this.display("none");},
      // события
      ready: function(handler) {this[0].onload = handler;},
      click: function(handler) {this[0].onclick = handler;},
      mover: function(handler) {this[0].onmouseover = handler;},
      mout:  function(handler) {this[0].onmouseout = handler;},
      mdown: function(handler) {this[0].onmousedown = handler;},
      mup:   function(handler) {this[0].onmouseup = handler;},
      // анимации
      roll_open: function(tSpeed, Height) {
        this.height(0);
        var iSpeed = (Height > 8)?(Height / 8):(1);
        var params = [];
        params["tSpeed"]  = tSpeed;
        params["iSpeed"]  = iSpeed;
        params["Height"]  = Height;
        params["iHeight"] = 0;
        params["iAnim"]   = ++nAnims;
        t_anims[params.iAnim] = 0;
        jsQuick.extend.roll_open(this, params);
      },
      roll_close: function(tSpeed, Height, bHide) {
        this.height(0);
        var iSpeed = (Height > 8)?(Height / 8):(1);
        var params = [];
        params["tSpeed"]  = tSpeed;
        params["iSpeed"]  = iSpeed;
        params["Height"]  = 0;
        params["iHeight"] = Height;
        params["bHide"]   = bHide;
        params["iAnim"]   = ++nAnims;
        t_anims[params.iAnim] = 0;
        jsQuick.extend.roll_close(this, params);
      },
      anim_show: function (tSpeed, Start, Opacity) {
        this.show();
        var params = [];
        params["tSpeed"]   = tSpeed;
        params["iOpacity"] = Start;
        params["Opacity"]  = Opacity;
        params["iAnim"]    = ++nAnims;
        t_anims[params.iAnim] = 0;
        jsQuick.extend.anim_show(this, params);
      },
      // свойства
      isShow: function() {
        if (this[0].style.display == "none") {return false;}
        else {return true;}
      }
    };
    jsQuick.main.init.prototype = jsQuick.main;
    
    return jsQuick;
  })();
  
  var rdash = /-([a-z])/ig,
  a_show,
  a_hide,
  r_up,
  r_down;
  
  // функции jsQuick
  // AJAX
  jsQuick.get = function(url, data, fun_callback) {jsQuick.extend.ajax("GET", url, data, fun_callback, true)};
  jsQuick.post = function(url, data, fun_callback) {jsQuick.extend.ajax("POST", url, data, fun_callback, true)};
  jsQuick.ajax = function(type, url, data, fun_callback, synch) {jsQuick.extend.ajax(type, url, data, fun_callback, synch)};
  jsQuick.Interpretation = function(text) {return reqInterpretation(text)};
  
  // расширения jsQuick
  jsQuick.extend = {
    roll_open: function(obj, p) {
      clearTimeout(t_anims[p.iAnim]);
      if (p.iHeight >= p.Height) {nAnims--; return;}
      p.iHeight += p.iSpeed;
      if (p.iSpeed >= 2 && (p.Height - p.iHeight) > 5) {
        var ratio = p.iHeight/p.Height;
        if ((0.75 > ratio && ratio >= 0.5) || (0.5 > ratio && ratio >= 0.325) || (0.325 > ratio && ratio >= 0.25) || (0.25 > ratio && ratio >= 0.1)) {p.iSpeed /= 1.15;}
      } else {p.iSpeed = 1;}
      obj.height(p.iHeight);
      t_anims[p.iAnim] = setTimeout(function (){return jsQuick.extend.roll_open(obj, p);}, p.tSpeed);
    },
    roll_close: function(obj, p) {
      clearTimeout(t_anims[p.iAnim]);
      if (p.iHeight <= p.Height) {nAnims--; if (p.bHide) {obj.hide();} return;}
      p.iHeight -= p.iSpeed;
      if (p.iSpeed >= 2 && (p.iHeight - p.Height) > 5) {
        var inc = (p.Height == 0)?(1):(0);
        var ratio = (p.Height + inc)/p.iHeight;
        if ((0.75 > ratio && ratio >= 0.5) || (0.5 > ratio && ratio >= 0.325) || (0.325 > ratio && ratio >= 0.25) || (0.25 > ratio && ratio >= 0.1)) {p.iSpeed /= 1.15;}
      } else {p.iSpeed = 1;}
      obj.height(p.iHeight);
      t_anims[p.iAnim] = setTimeout(function (){return jsQuick.extend.roll_close(obj, p);}, p.tSpeed);
    },
    anim_show: function(obj, p) {
      clearTimeout(t_anims[p.iAnim]);
      if (p.iOpacity >= p.Opacity) {nAnims--; return;}
      obj.css("opacity", p.iOpacity/100);
      obj.css("filter", "alpha(opacity="+p.iOpacity+")");
      p.iOpacity += 2.5;
      t_anims[p.iAnim] = setTimeout(function (){return jsQuick.extend.anim_show(obj, p);}, p.tSpeed);
    },
    ajax: function(type, url, data, fun_callback, synch) {
      var xhr;
      // создание объекта
      if (window.XMLHttpRequest) {xhr = new XMLHttpRequest();}
      else if (window.ActiveXObject) {
        try {xhr = new ActiveXObject("Msxml2.XMLHTTP");} 
        catch (e) {}                                   
        try {xhr = new ActiveXObject("Microsoft.XMLHTTP");} 
        catch (e) {}
      }
      // обработчик
      xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
          xhr.onreadystatechange = null;
          var request = reqInterpretation(xhr.responseText);
          return fun_callback(request);
        }
      }
      // отправка запроса
      if (type == "GET") {
        xhr.open("GET", url+'?'+data, synch);
        xhr.send(null);  
      } else {
        xhr.open("POST", url, synch);
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded charset=windows-1251");
        xhr.send(data);
      }
    }
  }

  function reqInterpretation(text) {
    var RezObj  = new Object(),
        Value   = "",
        Option  = ""
        bOption = false;
    // обработка текста
    for (var iCh = 0; iCh < text.length; iCh++) {
      if (!bOption) {
        if (text[iCh] == '{') {Option = "";}
        else {
          if (text[iCh] == '=' && text[iCh-1] == '}') {bOption = true;}
          else if (text[iCh] != '}') {Option += text[iCh];}
        }
      } else {
        if (text[iCh] == '[') {Value = "";}
        else {
          if (text[iCh] == ';' && text[iCh-1] == ']') {
            bOption = false;
            switch (Value) {
              case "_":     {Value = null; break;}
              case "true":  {Value = true; break;}
              case "false": {Value = false;break;}
              default: {if (Value*1) {Value *= 1;} break;}
            }
            RezObj[Option] = Value;
          } else if (text[iCh] != ']') Value += text[iCh];
        }
      }
    }
    return RezObj;
  }  
  
  function cssNameValidR(all, letter) {
    return letter.toUpperCase();
  }
  function cssNameValid(string) {
    return string.replace(rdash, cssNameValidR);
  }
  window.jsQuick = window.$ = jsQuick;
})(window)